import serial
import modbus_tk
import modbus_tk.defines as CST
from modbus_tk import modbus_rtu

import serial.tools.list_ports

import sys
import os

import time

import socket
import json

import datetime

import _thread

import smtplib
from email.mime.text import MIMEText
from email.header import Header

def licenseCommand(config,other):
    while(True):
        # socket服务轮询输出
        data= sk.recv(1024)
        print(data.decode())
        if(data.decode()=="cat"):
            

            log=open(dirname+"tempai_"+time.strftime('%Y%m%d')+".log","r")
            sendmailcontext=log.read()
            log.close()

            #send email
            message=MIMEText(str(sendmailcontext),"plain","utf-8")

            
            smtpObj=smtplib.SMTP(config['mailhost'])
            smtpObj.connect(config['mailhost'],config['mailport'])
            smtpObj.starttls()
            smtpObj.login(config['mailuser'],config['mailpassword'])
            smtpObj.sendmail(config['mailuser'],config['recvmailuser'],message.as_string())
            



def socketlink(config):
   
    sk=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #ipv4 socket udp
    ip_port=(config["serverip"],config["serverport"])
    sk.bind(ip_port)
    return sk

def getsystoken(config):
    if sys.platform=="windows":
        return config["windowslabel"]
    if sys.platform=="linux":
        return config["linuxlabel"]
    else :
        return config["windowslabel"]


#查找串口
def serchPort():

    systoken=getsystoken(config)

    ports_list=list(serial.tools.list_ports.comports())
    if len(ports_list)<=0:
        print("No ports")
    else:
        '''主动查询
        print("Here are ports:")
        p=1
        for comport in ports_list:
            print(p,".",list(comport)[0],list(comport)[1])
            p=p+1
    
        return ports_list[int(input("请选择端口序号:"))-1][0]
        '''
        #被动查询
        for comport in ports_list:
            if str.__contains__(list(comport)[1],systoken):
                return list(comport)[0]



def mod(config,PORT):       #在 PORT 参数位置写自己串行端口的端口号 如 com1 com2 或者 com3
    response = []           #名为response的列表用来存储反馈数据。
    alarm = ""              #用来存放异常信息
    try:
        
        # 设定串口参数———— 此处的设置必须和从机设备的端口参数一致
        # 示例中参数为 9600 8 N 1
        master = modbus_rtu.RtuMaster(serial.Serial(
                                                        port=PORT,                          #端口
                                                        baudrate=config["combaudrate"],     #波特率
                                                        bytesize=config["combytesize"],     #数据位
                                                        parity=config["comparity"],         #校验位
                                                        stopbits=config["comstopbits"]                        #停止位
                                                    ))

        master.set_timeout(3.0)           #timeout
        master.set_verbose(True)

        # 读保持寄存器
        response = master.execute(
                                config["deviceid"],         # 从站的站号 --->取决于从站的站号设置
                                config["modbusfunction"],   # modbus功能码 --->可以直接用功能码替代
                                config["memaddress"],       # 从站Modbus寄存器起始地址  --->数据格式 可以是 DEC 可以是 HEX
                                config["operatingnumber"],  # 被操作的寄存器的数量 --->包含起始地址的连续n个寄存器
                                output_value=config["crc"]  # 校验位
                            )  
        print(response)
        #todo write log file
        

        alarm = "ok" #正常返回提示
        return list(response),alarm


    except Exception as exc:
        print(str(exc))
        alarm = (str(exc))

    return response ,alarm  #异常返回故障信息

if __name__ == "__main__":
    dirname=os.path.abspath(__file__).split("tempaiC")[0]

    filepath=dirname+"/config.json"
    f=open(filepath,mode="r")
    config=json.load(f)
    f.close()

    port =serchPort()
    sk=socketlink(config)




    _thread.start_new_thread(licenseCommand,(config,"other"))


    if(len(port)!=0):
        
        while(True):


            time.sleep(45)

            logfile=open(dirname+"tempai_"+time.strftime('%Y%m%d')+".log","a")

            res=mod(config,port) # 如果需要连续执行  将mod()函数包含在循环语句的循环体中即可

            logfile.write(time.strftime('%m月%d日--%H:%M:%S')+"    [1]"+config["temp1devicename"]+"温度："+str(res[0][0])+"    [2]"+config["temp2devicename"]+"温度："+str(res[0][1])+"\n")
            logfile.close()




#todo 日志创建